package graph;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.chart.event.ChartProgressEvent;
import org.jfree.chart.event.ChartProgressListener;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.Range;
import org.jfree.data.time.*;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.DateCellRenderer;
import org.jfree.ui.NumberCellRenderer;
import org.jfree.ui.RectangleInsets;
import zagaynov.Properties;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class ZagaynovChart implements ChartProgressListener {
    private ChartPanel chartPanel;
    private DemoTableModel model;
    private JFreeChart chart;
    private Map<Double, List<Double>> results;
    private Properties properties;

    public ZagaynovChart(Map<Double, List<Double>> results, Properties properties) {
        this.properties = properties;
        this.results = results;
        JFrame applicationFrame = new JFrame("test1");
        JPanel mainPanel = new JPanel(new BorderLayout());

        XYDataset dataset = createDataSet(results, properties.getEquationsNumber());
        chart = createChart(dataset, properties);

        chart.addProgressListener(this);

        chartPanel = new ChartPanel(chart);
        //chartPanel.setPreferredSize(new Dimension(600, 270));
        chartPanel.setDomainZoomable(true);
        chartPanel.setRangeZoomable(true);
        javax.swing.border.CompoundBorder compoundborder = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4), BorderFactory.createEtchedBorder());
        chartPanel.setBorder(compoundborder);
        mainPanel.add(chartPanel);
        JPanel jpanel = new JPanel(new BorderLayout());
        jpanel.setPreferredSize(new Dimension(130, 120));
        jpanel.setBorder(BorderFactory.createEmptyBorder(0, 4, 4, 4));
        model = new DemoTableModel(properties.getEquationsNumber());
        XYPlot xyplot = (XYPlot) chart.getPlot();
        model.setValueAt(xyplot.getDataset().getSeriesKey(0), 0, 0);
        model.setValueAt(new Double("0.00"), 0, 1);
        model.setValueAt(new Double("0.00"), 0, 2);
        JTable jtable = new JTable(model);
        NumberCellRenderer numbercellrenderer = new NumberCellRenderer();
        jtable.getColumnModel().getColumn(1).setCellRenderer(numbercellrenderer);
        jtable.getColumnModel().getColumn(2).setCellRenderer(numbercellrenderer);
        JScrollPane jScrollPane = new JScrollPane(jtable);
        jpanel.add(jScrollPane);

        mainPanel.add(jpanel, "East");

        /*
       XYDataset dataset = createDataSet(results, properties.getEquationsNumber());
       JFreeChart chart = createChart(dataset, properties);
       ChartPanel chartPanel = new ChartPanel(chart);*/
       mainPanel.setPreferredSize(new java.awt.Dimension(600, 500));
       applicationFrame.setContentPane(mainPanel);
       applicationFrame.pack();
       applicationFrame.setVisible(true);
       applicationFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

    }

    private XYSeriesCollection createDataSet(Map<Double, List<Double>> results, int equationNumber) {
        XYSeriesCollection dataset = new XYSeriesCollection();

        for (int i = 0; i < equationNumber; i++) {
            XYSeries series = new XYSeries("N=" + (i+1));
            for (Map.Entry<Double, List<Double>> entry1 : results.entrySet()) {
                series.add(entry1.getKey(), entry1.getValue().get(i));

            }
            dataset.addSeries(series);
        }

        return dataset;
    }

    private JFreeChart createChart(XYDataset dataset, Properties properties) {
// create the chart...
        JFreeChart chart = ChartFactory.createXYLineChart(
                properties.getChartDescription(), // chart title
                "Time", // x axis label
                "C", // y axis label
                dataset, // data
                PlotOrientation.VERTICAL,
                true, // include legend
                true, // tooltips
                false // urls
        );
        chart.setBackgroundPaint(Color.white);
        XYPlot xyplot = (XYPlot) chart.getPlot();
        xyplot.setOrientation(PlotOrientation.VERTICAL);
        xyplot.setBackgroundPaint(Color.lightGray);
        xyplot.setDomainGridlinePaint(Color.white);
        xyplot.setRangeGridlinePaint(Color.white);
        xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyplot.setDomainCrosshairVisible(true);
        xyplot.setDomainCrosshairLockedOnData(true);
        xyplot.setRangeCrosshairVisible(true);
        XYItemRenderer xyitemrenderer = xyplot.getRenderer();
        xyitemrenderer.setSeriesPaint(0, Color.black);
        return chart;
    }
    @Override
    public void chartProgress(ChartProgressEvent chartprogressevent) {
        if (chartprogressevent.getType() != 2)
              return;
        if (chartPanel != null)
        {
            JFreeChart jfreechart = chartPanel.getChart();
            if (jfreechart != null)
            {
                XYPlot xyplot = (XYPlot)jfreechart.getPlot();
                XYDataset xydataset = xyplot.getDataset();
                double d = xyplot.getDomainCrosshairValue();

                for (int i=0; i<properties.getEquationsNumber(); i++) {
                    Comparable comparable = xydataset.getSeriesKey(i);
                    model.setValueAt(comparable, i, 0);
                    model.setValueAt(d, i, 1);
                    int n = (int)(d/properties.getTimeStepSize());
                    if (n>0) n-=1;
                    model.setValueAt(xydataset.getYValue(i, n), i, 2);


                }


            }
        }

    }
    class DemoTableModel extends AbstractTableModel implements TableModel {

        private Object data[][];

        public int getColumnCount() {
            return 3;
        }

        public int getRowCount() {
            return properties.getEquationsNumber();
        }

        public Object getValueAt(int i, int j) {
            return data[i][j];
        }

        public void setValueAt(Object obj, int i, int j) {
            data[i][j] = obj;
            fireTableDataChanged();
        }

        public String getColumnName(int i) {
            switch (i) {
                case 0: // '\0'
                    return "Series Name:";

                case 1: // '\001'
                    return "Time:";

                case 2: // '\002'
                    return "C:";

            }
            return null;
        }

        public DemoTableModel(int i) {
            data = new Object[i][3];
        }
    }

}
